package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.config.MinioConstantProperties;
import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumAttributeValueService;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.common.util.HttpClient;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.user.UserPaidAlbum;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.user.client.UserClientFeign;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;


@Slf4j
@Service
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

	@Autowired
	private AlbumInfoMapper albumInfoMapper;

	@Autowired
	private MinioConstantProperties minioConstantProperties;

	@Autowired
	private AlbumAttributeValueService albumAttributeValueService ;

	@Autowired
	private AlbumAttributeValueMapper albumAttributeValueMapper;

	@Autowired
	private AlbumStatMapper albumStatMapper;

	@Autowired
	private RabbitTemplate rabbitTemplate;

	@Autowired
	private UserClientFeign userClientFeign;



	/**
	 * 图片上传
	 * @param file
	 * @return
	 */
	@SneakyThrows
	@Override
	public Result<String> fileUpload(MultipartFile file) {
		//客户端对象初始化
		MinioClient minioClient = MinioClient.builder()
				//minio连接地址
				.endpoint(minioConstantProperties.getEndpointUrl())
				.credentials(minioConstantProperties.getAccessKey(),minioConstantProperties.getSecreKey())
				.build();
		//如果没有这个桶
		if (!(minioClient.bucketExists(BucketExistsArgs.builder().bucket("atguigu").build()))){
			//则创建
			minioClient.makeBucket(MakeBucketArgs.builder()
					.bucket("atguigu")
					.build());

		}else {
			//否则桶已存在
			System.out.println(minioConstantProperties.getBucketName()+"桶已存在");
		}

		String fileName = UUID.randomUUID().toString().replace("-","");
		//上传文件
		minioClient.putObject(PutObjectArgs.builder()
				.object(fileName)//文件名
				.stream(file.getInputStream(),file.getSize(),-1)//文件数
				.contentType(file.getContentType())//文件类型
				.bucket(minioConstantProperties.getBucketName())//上传到指定的桶
				.build());
		//获取文件访问地址
		//ip+端口号+桶名+文件名
		String url = minioConstantProperties.getEndpointUrl()+"/"+minioConstantProperties.getBucketName()+"/"+ fileName;
		return Result.ok(url);

	}

	/**
	 * 保存专辑
	 * @param albumInfoVo
	 */
	@Override
	@Transactional
	public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
		//获取userid
		Long userId = AuthContextHolder.getUserId();
		//创建专辑实体对象接收前端传来的数据
		AlbumInfo albumInfo = new AlbumInfo();
		//将相同属性复制
		BeanUtils.copyProperties(albumInfoVo,albumInfo);
		//将userid赋值过去
		albumInfo.setUserId(userId);
		//新专辑，所以一下属性为0
		albumInfo.setIncludeTrackCount(0);
		albumInfo.setIsFinished(0);
		albumInfo.setQualityScore("0");
		//保存到数据库
		save(albumInfo);
		//保存专辑统计数据
		AlbumStat albumStat = new AlbumStat();
		//保存专辑id
		albumStat.setAlbumId(albumInfo.getId());

		//保存播放量
		albumStat.setStatNum(0);
		albumStat.setStatType(SystemConstant.ALBUM_STAT_PLAY);
		albumStatMapper.insert(albumStat);
		//保存订阅量,默认为null
		albumStat.setStatType(SystemConstant.ALBUM_STAT_SUBSCRIBE);
		albumStat.setId(null);
		albumStatMapper.insert(albumStat);
		//保存购买量,默认为null
		albumStat.setStatType(SystemConstant.ALBUM_STAT_BROWSE);
		albumStat.setId(null);
		albumStatMapper.insert(albumStat);
		//保存评论数,默认为null
		albumStat.setStatType(SystemConstant.ALBUM_STAT_COMMENT);
		albumStat.setId(null);
		albumStatMapper.insert(albumStat);


		if (albumInfoVo.getAlbumAttributeValueVoList() !=null){
			List<AlbumAttributeValue> list = albumInfoVo.getAlbumAttributeValueVoList().stream().map(attrbulte -> {
				//new一个对象接收数据
				AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
				//从albumInfo获取用户id
				albumAttributeValue.setAlbumId(albumInfo.getId());
				//从前端获取标签id
				albumAttributeValue.setAttributeId(attrbulte.getAttributeId());
				//从前端获取属性值id
				albumAttributeValue.setValueId(attrbulte.getValueId());
				return albumAttributeValue;
			}).collect(Collectors.toList());
			//批量保存
			albumAttributeValueService.saveBatch(list);
		}
		//根据专辑是否公开判断是否将专辑写入es
		String isOpen = albumInfo.getIsOpen();
		//专辑是否公开
		if (isOpen.equals("1")){
			rabbitTemplate.convertAndSend("Album_Search_exchange","album-upper",albumInfo.getId()+"");
		}
	}

	/**
	 * 分页
	 * @param pageinfo
	 * @param albumInfoQuery
	 * @return
	 */
	@Override
	public Result<Page<AlbumListVo>> findUserAlbumPage(Page<AlbumListVo> pageinfo, AlbumInfoQuery albumInfoQuery) {
		Long userId = AuthContextHolder.getUserId();
		return Result.ok(albumInfoMapper.findUserAlbumPage(pageinfo, albumInfoQuery, userId));

	}

	/**
	 * 删除专辑
	 * @param albumId
	 */
	@Override
	@Transactional
	public void removeAlbumInfo(Long albumId) {
		Long userId = AuthContextHolder.getUserId();
		if (AuthContextHolder.getUserId() == userId) {
			//删除专辑表
			removeById(albumId);
			//删除标签表
			albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
					.eq(AlbumAttributeValue::getAlbumId, albumId));
			//删除统计表
			albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));

			//删除图片
		}
		//从es中删除专辑
		rabbitTemplate.convertAndSend("Album_Search_exchange","album-down",albumId);


	}

	/**
	 * 数据回显，修改专辑功能使用
	 * @param alumId
	 * @return
	 */
	@Override
	public Object getAlbumInfo(Long alumId) {
		//查询用户专辑数据
		AlbumInfo albumInfo = getOne(new LambdaQueryWrapper<AlbumInfo>()
				.eq(AlbumInfo::getUserId,AuthContextHolder.getUserId())
				.eq(AlbumInfo::getId,alumId));
		if (albumInfo==null){
			throw new GuiguException(201,"专辑不存在");
		}
		//查询标签信息
		List<AlbumAttributeValue> albumAttributeValue = albumAttributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>()
				.eq(AlbumAttributeValue::getAlbumId,alumId));
		albumInfo.setAlbumAttributeValueVoList(albumAttributeValue);
		return albumInfo;
	}


	/**
	 * 修改专辑
	 * @param albumId
	 * @param albumInfoVo
	 */
	@Override
	@Transactional
	public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
		//验证用户
		if (AuthContextHolder.getUserId()!=AuthContextHolder.getUserId()){
			throw new GuiguException(201,"您不是当前用户，请先登录");
		}
//		//用于接收前端的参数
		AlbumInfo albumInfo = new AlbumInfo();
		//将前端参数赋值给albumInfo的属性
		BeanUtils.copyProperties(albumInfoVo,albumInfo);

		albumInfo.setId(albumId);
		//保存
		updateById(albumInfo);
		//标签表要删除旧的，保存新的
		albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
				.eq(AlbumAttributeValue::getAlbumId,albumId));
		//保存新的
		if (albumInfoVo.getAlbumAttributeValueVoList() !=null){
			List<AlbumAttributeValue> list = albumInfoVo.getAlbumAttributeValueVoList().stream().map(attrbulte -> {
				//new一个对象接收数据
				AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();

				BeanUtils.copyProperties(albumInfoVo.getAlbumAttributeValueVoList(),albumAttributeValue);
				//从albumInfo获取用户id
				albumAttributeValue.setAlbumId(albumInfo.getId());
				//从前端获取标签id
				albumAttributeValue.setAttributeId(attrbulte.getAttributeId());
				//从前端获取属性值id
				albumAttributeValue.setValueId(attrbulte.getValueId());
				return albumAttributeValue;
			}).collect(Collectors.toList());
			//批量保存
			albumAttributeValueService.saveBatch(list);
		}
		//如果不公开
		//-从es中删除专辑
		String isOpen = albumInfoVo.getIsOpen();
		if (isOpen.equals("0")){

			rabbitTemplate.convertAndSend("Album_Search_exchange","album-down",albumId+"");
			rabbitTemplate.convertAndSend("Album_Search_exchange","album-redis",albumId+"");

		}else {
			rabbitTemplate.convertAndSend("Album_Search_exchange","album-upper",albumId+"");
		}
	}

	/**
	 * 查询添加声音的专辑列表
	 * @return
	 */
	@Override
	public Object findUserAllAlbumList() {
		//条件查询：当前用户、审核通过的、未完结的专辑列表
		Page<AlbumInfo> albumInfoPage = albumInfoMapper.selectPage(new Page<>(1, 10), new LambdaQueryWrapper<AlbumInfo>()
				.eq(AlbumInfo::getUserId, AuthContextHolder.getUserId())
				.eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS)
				.eq(AlbumInfo::getIsFinished, 0).orderByDesc(AlbumInfo::getUpdateTime));
		return albumInfoPage.getRecords();
	}

	@Override
	public Map<String,Object> getAlbumStatMap(Long albumId) {
		List<AlbumStat> albumStats = albumStatMapper.selectList(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
		Map<String, Object> albumStat = albumStats.stream().collect(Collectors.toMap(
				AlbumStat::getStatType,
				AlbumStat::getStatNum)
		);
		return albumStat;
	}

	/**
	 * 查询专辑标签信息
	 * @param albumId
	 * @return
	 */
	@Override
	public List<AlbumAttributeValue> getAlbumInfoAttributeList(Long albumId) {
		return albumAttributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>()
				.eq(AlbumAttributeValue::getAlbumId,albumId));
	}

	@Override
	public Boolean isCanComment(Map<String,Long>param) {
		//获取专辑的收费类型
		AlbumInfo albumInfo = albumInfoMapper.selectOne(new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getId, param.get("albumId")));
		String payType = albumInfo.getPayType();
		switch (payType){
			//免费
			case "0101" ->{
				//免费的可以直接评论
				return true;
			}
			//vip免费
			case "0102" ->{
				//vip可以评论
				//判断是不是vip
				Long aLong = AuthContextHolder.getvipExpireTime();
				if (aLong >System.currentTimeMillis()){
					//是VIP
					return true;
				}else {
					return false;
				}
			}
			//付费
			case "0103" ->{
				//购买了专辑或声音可以评论
				return userClientFeign.isOwn(param.get("userId"),param.get("albumId"),param.get("trackId"));
			}
		}
		return false;
	}
}
